/****************************************************************************
*                                                                           *
* floor.cpp 																*
*                                                                           *
* ALaRI 2008												                *
*                                                                           *
****************************************************************************/


/****************************************************************************
* Includes										                            *
****************************************************************************/
#include "floor.h" // me
#include "../../core/prop/sensor.h"
#include "../../core/prop/sensorrepository.h"

#include <memory>

/****************************************************************************
* CFloorPlan 													 			*
****************************************************************************/

/****************************************************************************
* Public workers												 			*
****************************************************************************/
CFloorWidget::CFloorWidget(int nWidth /*= 400*/, int nHeight /*= 200*/) 
	: m_nWidth(nWidth), m_nHeight(nHeight)
{
	m_pDrawManager = new CDrawManager(this, m_nWidth, m_nHeight);
	assert(NULL != m_pDrawManager);
	connect(m_pDrawManager, SIGNAL(updated()), this, SLOT(update())); 
	connect(m_pDrawManager, SIGNAL(pointAddedOrRemoved(CSensorPoint*, bool)), this, SLOT(addOrRemoveSensor(CSensorPoint*, bool))); 
	
	setBaseSize(QSize(m_nWidth, m_nHeight));
	setMinimumSize(m_nWidth, m_nHeight);
	setMaximumSize(m_nWidth, m_nHeight);
	setCursor(Qt::CrossCursor);
	
	setToolTip(QString("[%1cm X %2cm]").arg(m_nWidth).arg(m_nHeight));
}

QImage CFloorWidget::convertToImage() const
{
	assert(NULL != m_pDrawManager);
	return m_pDrawManager->getImage();
}

void CFloorWidget::setPenWidth(int nWidth)
{
	assert(NULL != m_pDrawManager);
	m_pDrawManager->setPenWidth(nWidth);
}

void CFloorWidget::setPenColor(const QRgb& rgbColor)
{
	assert(NULL != m_pDrawManager);
	m_pDrawManager->setPenColor(QColor(rgbColor));
}

bool CFloorWidget::isPointInside(const QPoint &rPoint)
{
	if (false == isValid())
		return false;
	return (rPoint.x() < m_nWidth && rPoint.y() < m_nHeight &&
		rPoint.x() >= 0 && rPoint.y() >= 0); 
}

void CFloorWidget::paintEvent(QPaintEvent *pEvent)
{
	// TODO: redraw only a single region
	assert(NULL != m_pDrawManager);
	QRegion paintRegion = pEvent->region();
	m_pDrawManager->redraw(paintRegion);
}

QSize CFloorWidget::sizeHint() const
{
	return QSize(m_nWidth, m_nHeight);
}

void CFloorWidget::setAirColor(const QRgb& rgbColor)
{
	setAutoFillBackground(true);
	QPalette pal = palette();
	pal.setBrush(QPalette::Base, QColor(rgbColor));
	setBackgroundRole(QPalette::Base);
	setPalette(pal);
	m_pDrawManager->setBackgroundColor(QColor(rgbColor));
}

void CFloorWidget::resize(int nWidth, int nHeight)
{
	assert(NULL != m_pDrawManager);
	// set new size	
	m_nWidth = nWidth;
	m_nHeight = nHeight;
	setToolTip(QString("[%1cm X %2cm]").arg(m_nWidth).arg(m_nHeight));
	setBaseSize(QSize(nWidth, nHeight));
	setMinimumSize(nWidth, nHeight);
	setMaximumSize(nWidth, nHeight);
	// reset draw manager
	m_pDrawManager->reset();
}

void CFloorWidget::deleteCurrentShape()
{
	assert(NULL != m_pDrawManager);
	m_pDrawManager->deleteCurrentShape();
}

void CFloorWidget::mousePressEvent(QMouseEvent *pMouseEvent)
{
	assert(NULL != pMouseEvent);
	assert(NULL != m_pDrawManager);

	if (true == isPointInside(pMouseEvent->pos()))
	{
		grabMouse();
		m_pDrawManager->processEvent(pMouseEvent);
	}
}

void CFloorWidget::mouseMoveEvent(QMouseEvent *pMouseEvent)
{
	assert(NULL != pMouseEvent);
	assert(NULL != m_pDrawManager);

	if (true == isPointInside(pMouseEvent->pos()))
		m_pDrawManager->processEvent(pMouseEvent);
}

void CFloorWidget::mouseReleaseEvent(QMouseEvent *pMouseEvent)
{
	assert(NULL != m_pDrawManager);
	assert(NULL != pMouseEvent);

	releaseMouse();
	m_pDrawManager->processEvent(pMouseEvent);
}

void CFloorWidget::drawWall()
{
	assert(NULL != m_pDrawManager);
	if (true == isValid())
		m_pDrawManager->startDrawLine();
}

void CFloorWidget::putSensor()
{
	assert(NULL != m_pDrawManager);
	if (true == isValid())
		m_pDrawManager->startDrawPoint();
}

void CFloorWidget::drawDemo()
{
	assert(NULL != m_pDrawManager);
	if (true == isValid())
		m_pDrawManager->drawDemo();
}

void CFloorWidget::drawRoom()
{
	assert(NULL != m_pDrawManager);
	if (true == isValid())
		m_pDrawManager->startDrawRect();
}

void CFloorWidget::drawSpecial(const QPoint& qPointFrom, const QPoint& qPointTo, int nType)
{
	assert(NULL != m_pDrawManager);
	if (isPointInside(qPointFrom) && isPointInside(qPointTo))
		m_pDrawManager->addShape(qPointFrom, qPointTo, nType);
}

void CFloorWidget::drawRoundRoom()
{
	assert(NULL != m_pDrawManager);
	if (true == isValid())
		m_pDrawManager->startDrawEllipse();
}

void CFloorWidget::setIdle()
{
	assert(NULL != m_pDrawManager);
	if (true == isValid())
		m_pDrawManager->startIdle();
}

void CFloorWidget::addOrRemoveSensor(CSensorPoint *pSensorPoint, bool bAdd)
{
	assert(pSensorPoint != NULL);
	QPoint *p = dynamic_cast<QPoint*>(pSensorPoint); 
	assert(p != NULL);
	if (NULL == p)
		return; 
	if (true == bAdd)
	{
		std::auto_ptr<CSensor> spSensor(new CSensor(m_nWidth, m_nHeight, 
			p->x(), p->y(), pSensorPoint->getName()));
		CSensorRepository::inst()->addSensor(spSensor.release());
	}
	else CSensorRepository::inst()->removeSensor(p->x(), p->y());
}

/****************************************************************************
* End of file																*
****************************************************************************/